package com.spmsys.logUtil;

import com.alibaba.fastjson.JSONObject;
import com.spmsys.util.DateUtil;
import com.spmsys.util.ServletUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.jetbrains.annotations.NotNull;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;


/**
 * 日志类
 */
public class LOGGER {
    private static Thread logThread = null;
    private static long recordingInterval = 30 * 1000;
    private static final List<String> logs = new ArrayList<>();
    private static final String logPath = System.getProperty("java.class.path").substring(0, System.getProperty("java.class.path").indexOf("SPMSYS\\") + 7) + "log\\";

    public static Thread getLogThread() {
        return logThread;
    }

    public static long getRecordingInterval() {
        return recordingInterval;
    }

    public static List<String> getLogs() {
        return logs;
    }

    public static String getLogPath() {
        return logPath;
    }

    public static void setRecordingInterval(long recordingInterval) {
        LOGGER.recordingInterval = recordingInterval;
    }

    /**
     * 获取请求日志方法
     *
     * @param ID  ID
     * @param req 请求对象
     * @return 请求日志
     */
    public static @NotNull String request_log(String ID, @NotNull HttpServletRequest req) {
        StringBuilder Headers = new StringBuilder();
        StringBuilder Body = new StringBuilder();
        String URL = req.getRequestURI();
        String HttpMethod = req.getMethod();
        String ContentType = req.getContentType();
        JSONObject HeadersJson = ServletUtil.getRequestHeaders(req);
        JSONObject BodyJson = ServletUtil.getRequestBody(req);
        for (String key : HeadersJson.keySet()) {
            Headers.append("\t").append(key).append(":").append(HeadersJson.getString(key)).append("\n");
        }
        if (BodyJson != null) {
            for (String key : BodyJson.keySet()) {
                Body.append("\t").append(key).append(":").append(BodyJson.getString(key)).append("\n");
            }
        }
        //返回数据
        return "ID:" + ID + "\n"
                + "URL:" + URL + "\n"
                + "Http-method:" + HttpMethod + "\n"
                + "Content-Type:" + ContentType + "\n"
                + "Headers:\n" + Headers
                + "Body:\n" + Body;
    }

    /**
     * 获取响应日志方法
     *
     * @param ID   ID
     * @param resp 响应对象
     * @return 响应日志
     */
    public static @NotNull String response_log(String ID, @NotNull HttpServletResponse resp) {
        StringBuilder Headers = new StringBuilder();
        StringBuilder Body = new StringBuilder();
        int ResponseCode = resp.getStatus();
        String ContentType = resp.getContentType();
        JSONObject HeadersJson = ServletUtil.getResponseHeaders(resp);
        JSONObject BodyJson = ServletUtil.getResponseBody(resp);
        for (String key : HeadersJson.keySet()) {
            Headers.append("\t").append(key).append(":").append(HeadersJson.getString(key)).append("\n");
        }
        if (BodyJson != null) {
            for (String key : BodyJson.keySet()) {
                Body.append("\t").append(key).append(":").append(BodyJson.getString(key)).append("\n");
            }
        }
        //返回数据
        return "ID:" + ID + "\n"
                + "Response-Code:" + ResponseCode + "\n"
                + "Content-Type:" + ContentType + "\n"
                + "Headers:\n" + Headers
                + "Body:\n" + Body;
    }

    /**
     * 写入日志方法
     *
     * @param logContent 日志内容
     */
    public static void record_log(String logContent) {
        String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis());
        String log = "BEGIN:\n\n" + "TIME:" + time + "\n" + "CONTENT:\n" + logContent + "END\n\n";
        logs.add(log);
    }

    /**
     * 开始记录日志方法
     *
     * @return 日志线程
     */
    public static Thread start_record_log() {
        if (logThread != null) {
            return logThread;
        }
        logThread = new Thread(() -> {
            System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis()) + "日志记录开始");
            //进入循环开始处理日志（发出终止信号后终止）
            while (!Thread.interrupted()) {
                long dayStartTimestamp = DateUtil.dayTimeInMillis();
                try {
                    String fileName = new SimpleDateFormat("yyyy-MM-dd").format(dayStartTimestamp) + ".txt";
                    File file = new File(logPath + fileName);
                    if (!file.exists() && !file.createNewFile()) {
                        throw new RuntimeException(logPath + fileName + "文件创建失败");
                    }
                    //写入日志（发出终止信号或超出当天则终止）
                    System.out.println(logPath + fileName + "日志文件开始写入");
                    while (!Thread.interrupted() && System.currentTimeMillis() <= dayStartTimestamp + 24 * 60 * 60 * 1000) {
                        try (FileWriter fileWriter = new FileWriter(file.getAbsoluteFile(), true); BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) {
                            System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis()) + "日志开始写入文件");
                            StringBuilder data = new StringBuilder();
                            for (String val : logs) {
                                data.append(val);
                            }
                            bufferedWriter.write(data.toString());
                            //清空日志缓冲区
                            logs.clear();
                            System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis()) + "日志写入文件成功");
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                        //每隔recordingInterval时间写入一次
                        Thread.sleep(recordingInterval);
                    }
                    System.out.println(logPath + fileName + "日志文件结束写入");
                } catch (Exception e) {
                    System.out.println("errorMessage:" + e.getMessage());
                    break;
                }
            }
            System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis()) + "日志记录终止");
        });
        return logThread;
    }
}
